package com.ds.lens.data.service.dao;

import com.github.pagehelper.Page;
import com.ds.lens.data.service.dao.entity.LensMonitor;
import com.ds.lens.data.service.dao.mybatis.CollectionMybatisLanguageDriver;
import com.ds.lens.data.service.dao.sql.provider.LensMonitorSqlProvider;
import com.ds.lens.data.vo.in.v2.monitor.LensMonitorListInVO;
import com.ds.lens.data.vo.in.v2.monitor.state.LensMonitorStateUpdateVO;
import org.apache.ibatis.annotations.*;
import org.apache.ibatis.type.JdbcType;
import org.springframework.stereotype.Repository;

import java.util.Date;
import java.util.List;

@Repository
public interface LensMonitorDao {

    String COLUMNS = "id, name, integration_id, detection_method, application_id, state, mute, mute_start_time, " +
            "mute_end_time, is_delete, run_status, tags, version, creator, created_time, mender, modified_time, version_time ";

    @Update({
            "update lens_monitor set is_delete=1",
            "where id = #{id,jdbcType=BIGINT}"
    })
    int deleteByPrimaryKey(Long id);

    @Lang(CollectionMybatisLanguageDriver.class)
    @Update({
            "update lens_monitor set is_delete=1",
            "where id in (#{ids})"
    })
    int deleteByPrimaryKeys(@Param("ids") List<Long> ids);

    @InsertProvider(type = LensMonitorSqlProvider.class, method = "insertSelective")
    @Options(useGeneratedKeys = true, keyColumn = "id")
    int insertSelective(LensMonitor record);

    @Select({
            "select",
            COLUMNS,
            " from lens_monitor",
            " where id = #{id,jdbcType=BIGINT} and is_delete = 0"
    })
    @Results(id = "lensMonitor", value = {
            @Result(column = "id", property = "id", jdbcType = JdbcType.BIGINT, id = true),
            @Result(column = "name", property = "name", jdbcType = JdbcType.VARCHAR),
            @Result(column = "integration_id", property = "integrationId", jdbcType = JdbcType.BIGINT),
            @Result(column = "detection_method", property = "detectionMethod", jdbcType = JdbcType.TINYINT),
            @Result(column = "application_id", property = "applicationId", jdbcType = JdbcType.BIGINT),
            @Result(column = "state", property = "state", jdbcType = JdbcType.SMALLINT),
            @Result(column = "mute", property = "mute", jdbcType = JdbcType.BIT),
            @Result(column = "mute_start_time", property = "muteStartTime", jdbcType = JdbcType.TIMESTAMP),
            @Result(column = "mute_end_time", property = "muteEndTime", jdbcType = JdbcType.TIMESTAMP),
            @Result(column = "is_delete", property = "isDelete", jdbcType = JdbcType.BIT),
            @Result(column = "run_status", property = "runStatus", jdbcType = JdbcType.TINYINT),
            @Result(column = "tags", property = "tags", jdbcType = JdbcType.VARCHAR),
            @Result(column = "version", property = "version", jdbcType = JdbcType.INTEGER),
            @Result(column = "creator", property = "creator", jdbcType = JdbcType.VARCHAR),
            @Result(column = "created_time", property = "createdTime", jdbcType = JdbcType.TIMESTAMP),
            @Result(column = "mender", property = "mender", jdbcType = JdbcType.VARCHAR),
            @Result(column = "modified_time", property = "modifiedTime", jdbcType = JdbcType.TIMESTAMP),
            @Result(column = "version_time", property = "versionTime", jdbcType = JdbcType.TIMESTAMP)
    })
    LensMonitor selectByPrimaryKey(Long id);

    @Lang(CollectionMybatisLanguageDriver.class)
    @Select({
            "select",
            COLUMNS,
            " from lens_monitor",
            " where is_delete = 0 and id in (#{ids})"
    })
    @ResultMap("lensMonitor")
    List<LensMonitor> selectByPrimaryKeys(@Param("ids") List<Long> ids);

    @UpdateProvider(type = LensMonitorSqlProvider.class, method = "updateByPrimaryKeySelective")
    int updateByPrimaryKeySelective(LensMonitor record);


    @Lang(CollectionMybatisLanguageDriver.class)
    @Update({"update lens_monitor set mute=#{mute}, modified_time=#{modifiedTime},",
            "mute_start_time=#{startTime}, mute_end_time=#{endTime}",
            " where id in (#{ids})"
    })
    int updateMuteByPrimaryKeys(@Param("ids") List<Long> ids, @Param("mute") boolean mute,
                                @Param("startTime") Date startTime, @Param("endTime") Date endTime,
                                @Param("modifiedTime") Date modifiedTime);

    @Lang(CollectionMybatisLanguageDriver.class)
    @Update({"update lens_monitor set state=#{state} ",
            " where id in (#{ids})"
    })
    int updateStateByPrimaryKeys(@Param("ids") List<Long> ids, @Param("state") Integer state);

    @Select({"<script>",
            "select",
            COLUMNS,
            "from lens_monitor",
            " where is_delete=0 ",
            "<if test=\"applicationIds!=null and applicationIds.size >0\">",
            " and application_id in ",
            "<foreach collection='applicationIds' item='applicationId' separator=',' open='(' close=')' >",
            "#{applicationId}",
            "</foreach>",
            "</if>",
            "<if test=\"states!=null and states.size > 0\">",
            " and state in ",
            "<foreach collection='states' item='state' separator=',' open='(' close=')' >",
            "#{state}",
            "</foreach>",
            "</if>",
            "<if test=\"mute!=null\">",
            " and mute = #{mute}",
            "</if>",
            "<if test=\"name!=null and name != '' \">",
            " and name like concat(#{name},'%')",
            "</if>",
            "<if test=\"id!=null\">",
            " and id = #{id}",
            "</if>",
            "<if test=\"tags!=null and tags.size > 0\">",
            "<foreach collection='tags' item='tag' >",
            " and FIND_IN_SET(#{tag},tags) ",
            "</foreach>",
            "</if>",
            "<if test=\"integrationIds!=null and integrationIds.size > 0\">",
            " and integration_id in ",
            "<foreach collection='integrationIds' item='integrationId' separator=',' open='(' close=')' >",
            "#{integrationId}",
            "</foreach>",
            "</if>",
            "<if test=\"detectionMethods!=null and detectionMethods.size > 0\">",
            " and detection_method in ",
            "<foreach collection='detectionMethods' item='detectionMethod' separator=',' open='(' close=')' >",
            "#{detectionMethod}",
            "</foreach>",
            "</if>",
            "<if test=\"sort != null \"> ",
            " order by ${sort.field} ${sort.order}",
            "</if>",
            "</script>"
    })
    @ResultMap("lensMonitor")
    Page<LensMonitor> listMonitorByAppIdOrTags(LensMonitorListInVO monitorListInVO);

    @Select({"select id, version, is_delete, run_status, application_id, modified_time",
            "from lens_monitor where is_delete = 0"
    })
    @ResultMap("lensMonitor")
    List<LensMonitor> listAvailableMonitorState();

    @Select({"select id, version, is_delete, run_status, application_id, modified_time",
            "from lens_monitor where modified_time > #{lastModifiedTime}"
    })
    @ResultMap("lensMonitor")
    List<LensMonitor> listUpdatedMonitorState(@Param("lastModifiedTime") Date lastModifiedTime);


    @Select({"<script>",
            "select",
            COLUMNS,
            "from lens_monitor",
            " where is_delete=0 and application_id = #{applicationId}",
            "<foreach collection='tags' item='tag' >",
            " and FIND_IN_SET(#{tag},tags) ",
            "</foreach>",
            "</script>"
    })
    @ResultMap("lensMonitor")
    List<LensMonitor> listByTagsAppId(@Param("applicationId") Long applicationId, @Param("tags") List<String> tags);


    @Select({"select state from lens_monitor",
            " where is_delete=0 and id = #{id} and version = #{version} "
    })
    Integer selectStateByIdVersion(@Param("id") Long id, @Param("version") Integer version);

    @Update({"update lens_monitor set state=#{state} ",
            " where id=#{id} and version = #{version} and state=#{preState}"
    })
    int updateStateByIdVersion(LensMonitorStateUpdateVO stateUpdateVO);

}
